Dora 的编程语言教程15 分钟掌握 YueScript本页总览15 分钟掌握 YueScript 提示 本教程提供了 YueScript 的快速概览,它是一种 Lua 的现代替代方案。YueScript 继承了 Lua 的特性,同时引入了语法糖和类似 Python 的编码风格。因为 YueScript 是 MoonScript 的方言,本教程修改自"15 分钟掌握 MoonScript",并假设你有一定的编程经验并熟悉 Lua。如果你还不熟悉 Lua,可以参考 Lua 官方文档 进行学习。 与 Lua 不同,YueScript 不使用 do、then 或 end,而是采用类似 Python 的缩进语法。 -- 两个横杠表示注释。注释会一直到行尾。-- YueScript 编译成 Lua 后不会保留注释。 1. 赋值 hello = "world"a, b, c = 1, 2, 3hello = 123 -- 覆盖之前的 `hello`x = 0x += 10 -- x = x + 10s = "hello "s ..= "world" -- s = s .. "world"b = falseb and= true or false -- b = b and (true or false) 2. 字面量和运算符 字面量的使用与Lua几乎一致。字符串可以在行中间换行而不需要使用\。 some_string = "example" -- 等效于 local some_string = "exa\nmple" 字符串中可以插入变量值,这些值会先被计算,再插入到字符串中。 some_string = "这是一个 #{some_string}" -- 变为 '这是一个 exa\nmple' 2.1. 函数字面量 函数使用箭头符号来定义: my_function = -> -- 编译为 function() endmy_function() -- 调用空函数 函数可以不使用括号来调用。如果需要优先级,可以使用括号。 func_a = -> print "Hello World!"func_b = -> value = 100 print "值是:#{value}" 如果函数不需要参数,可以使用 () 或 ! 来调用。 func_a!func_b() 可以通过在箭头前加参数名的列表来为函数传递参数: sum = (x, y) -> x + y -- 最后一个表达式将作为返回值print sum(5, 10) Lua 中有一种将第一个参数作为"self"对象的惯例。使用 => 代替 -> 会自动创建一个 self 变量。@x 是 self.x 的简写。 func = (num) => @value + num 也可以在函数中使用默认参数: a_function = (name = "某人", height = 100) -> print "你好,我叫#{name}。\n我的身高是#{height}。" 因为默认参数在 Lua 中是在函数体内计算的,所以可以引用之前的参数: some_args = (x = 100, y = x + 1000) -> print(x + y) 注意事项 减号既可以作为一元运算符,也可以作为二元减法运算符。建议在二元运算符之间留有空格,以避免冲突。 a = x - 10 -- a = x - 10b = x-10 -- b = x - 10c = x -y -- c = x(-y)d = x- z -- d = x - z 当变量与字符串字面量之间没有空格时,函数调用优先于后续表达式: x = func"hello" + 100 -- func("hello") + 100y = func "hello" + 100 -- func("hello" + 100) 函数的参数可以跨多行,只要保持缩进即可。缩进也可以嵌套。 my_func 5, -- 调用 my_func(5, 8, another_func(6, 7, 9, 1, 2), 5, 4) 8, another_func 6, 7, -- 调用 another_func(6, 7, 9, 1, 2) 5, 4 如果一个函数在代码块的开头使用,其缩进可以与块内的缩进不同。 if func 1, 2, 3, -- 调用 func(1, 2, 3, "hello", "world") "hello", "world" print "hello" 3. 表(Tables) 表通过花括号定义,类似于Lua: some_values = [1, 2, 3, 4] -- 推荐使用 [] 而不是 {} 来表示数组类型的表 表的元素可以换行,而不需要逗号分隔。 some_other_values = [ 5, 6 7, 8] 表字段赋值使用 : 而不是 =: profile = { name: "Bill" age: 200 "favorite food": "rice"} 对于键值表,花括号可以省略。 y = type: "dog", legs: 4, tails: 1profile = height: "4 feet", shoe_size: 13, favorite_foods: -- 嵌套表 foo: "冰淇淋", bar: "甜甜圈" 通过 : 前缀操作符,可以使用与变量同名的键构建表。 hair = "金色"height = 200person = {:hair, :height} 在Lua中,可以使用 [] 来表示非字符串或非数字的键。 t = [1 + 2]: "hello" "hello world": true -- 字符串字面量不需要使用 [] 3.1. 表推导 表推导类似于数组推导,可以通过遍历生成一个新的表。 items = [1, 2, 3, 4]doubled = [item * 2 for item in *items] 使用 when 来筛选出需要的值。 slice = [item for item in *items[1, 2] when item % 2 == 0] 推导中的 for 子句可以链式调用。 x_coords = [4, 5, 6, 7]y_coords = [9, 2, 3]points = [ [x, y] for x in *x_coords for y in *y_coords] 你可以使用类似的结构遍历表中的键值对: thing = color: "red", name: "thing", width: 123thing_copy = {k, v for k, v in pairs thing} 4. 控制结构 have_coins = falseif have_coins print "有硬币"else print "没硬币" 你可以使用 then 来简写单行 if。 result = if have_coins then "有硬币" else "没硬币" unless 是 if 的反义词。 unless os.date("%A") == "Monday" print "今天不是周一!" 5. 面向对象编程 类通过 class 关键字定义,后面跟一个标识符,通常使用驼峰命名法。类的特殊函数 new 用于初始化实例。 class Inventory new: => @items = {} add_item: (name) => @items[name] = 0 unless @items[name] @items[name] += 1 实例的创建方式与调用函数类似: inv = Inventory!inv\add_item "T恤"inv\add_item "裤子" 实例中的类变量可以在类中共享。 class Person clothes: [] give_item: (name) => table.insert @clothes, namea = Person!b = Person!a\give_item "裤子"b\give_item "衬衫"-- 打印出 "裤子" 和 "衬衫"print item for item in *a.clothes 6. 作用域 所有值默认是局部的。可以使用 global 关键字将变量声明为全局变量。 global var_1, var_2 你还可以使用 do 手动创建作用域: do x = 5print x -- nil 延伸阅读 完整的 YueScript 文档请访问 YueScript官方网站。